package net.adetech.dcweb.core.job;

import com.alibaba.fastjson.JSONObject;
import net.adetech.dcweb.core.common.entity.CommonAdminuser;
import net.adetech.dcweb.core.common.service.ICommonAdminuserService;
import net.adetech.dcweb.core.dc.entity.DcAlarm;
import net.adetech.dcweb.core.dc.entity.DcData;
import net.adetech.dcweb.core.dc.entity.DcInfo;
import net.adetech.dcweb.core.dc.entity.DcPeople;
import net.adetech.dcweb.core.dc.service.*;
import net.adetech.dcweb.core.ddpush.utils.IDDPushService;
import net.adetech.police.api.IPoliceInterfaceService;
import net.adetech.police.entity.PCGTicket;
import net.adetech.police.entity.People;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by zhangsong on 2017/9/29.
 */
@Component
@Configurable
@EnableScheduling
public class DcJobs {

    @Autowired
    private IDcInfoService iDcInfoService;

    @Autowired
    private IPoliceInterfaceService policeInterfaceService;

    @Autowired
    private IDcDataService iDcDataService;

    @Autowired
    private IDcAlarmService iDcAlarmService;

    @Autowired
    private IDcSmsService iDcSmsService;

    @Autowired
    private ICommonAdminuserService iCommonAdminuserService;

    @Autowired
    private IDcPeopleService iDcPeopleService;

    @Autowired
    private IDDPushService iddPushService;

    @Value("${fileWatch.sourcePath}")
    private String sourcePath;

    @Value("${fileWatch.targetPath}")
    private String targetPath;


    private static boolean pushed =false;

    public void syncPeopleJobs()
    {
        List<DcInfo> infos = iDcInfoService.getDcInfoListByState("2");
        HashSet<String> sfzhSet = new HashSet<>();
        for (DcInfo info:infos)
        {
            if (info.getCardNo()!=null&&info.getCardNo().length()==18)
            {
                sfzhSet.add(info.getCardNo());
            }
        }
        Iterator<String> it = sfzhSet.iterator();
        while (it.hasNext())
        {
            String sfzh = it.next();
            DcPeople people = iDcPeopleService.findByCardNo(sfzh);
            if (people==null)
            {
                syncPeopleInfo(sfzh);
            }
        }

    }



    /**
     * 部署在外网时定时任务
     */
    public void reportCurrentByFile()
    {
        File sourceDir = new File(sourcePath);
        File[] files = sourceDir.listFiles();
        for (File sourceFile:files)
        {
            if (sourceFile.getName().indexOf(".xml")>-1)
            {
                handleFile(sourceFile);
            }
        }
    }





    /**
     * 部署在内网时定时任务
     */
    @Scheduled(cron = "0/20 1 * * * *")

    public void reportCurrentByCron() {


        if (!pushed)
        {
            iDcSmsService.sendMessage("18660577316","测试发送");
            pushed =true;
        }


        List<DcInfo> infoList = iDcInfoService.getDcInfoListByState("2");//获取所有当前布控人员身份证号
        List<String> sfzhList = new ArrayList<String>(); //所有布控身份证号集合
        for (DcInfo info : infoList) {
            sfzhList.add(info.getCardNo());
        }
        if (sfzhList.size() < 1) {
            return;
        }

        //分组查询 一次查30个
        int groupSize = 500;
        for (int i = 0; i < sfzhList.size() / groupSize + 1; i++) {
            List<String> sfzhGroupList = new ArrayList<String>();
            for (int j = i * 10; j < (i + 1) * groupSize && j < sfzhList.size(); j++) {
                sfzhGroupList.add(sfzhList.get(j));
            }
            if (sfzhGroupList.size() > 0) {
                List<PCGTicket> pcgTicketList = queryTicketList(sfzhGroupList);
                for (PCGTicket ticket : pcgTicketList) {
                    handleTicket(ticket, infoList);
                    syncPeopleInfo(ticket.getSfzh());
                }
            }
        }
    }




    private void handleFile(File sourceFile)
    {
        File targetFile = new File(targetPath+sourceFile.getName());
        //将xml文件移至备份文件夹
        try {
            copyFile(sourceFile,targetFile);
            sourceFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<PCGTicket> pcgTicketList = getTicketListByFile(targetFile);
        List<DcInfo> infoList = this.iDcInfoService.getDcInfoListByState("2");

        for (PCGTicket ticket:pcgTicketList)
        {
            handleTicket(ticket,infoList);
        }


    }

    public long copyFile(File sourceFile,File targetFile) throws Exception{
        File targetDir = new File(targetPath);
        if (!targetDir.exists())
        {
            targetDir.mkdir();
        }
        long time=new Date().getTime();
        int length = 2097152;
        FileInputStream in=new FileInputStream(sourceFile);
        FileOutputStream out=new FileOutputStream(targetFile);
        FileChannel inC=in.getChannel();
        FileChannel outC=out.getChannel();
        int i=0;
        while(true){
            if(inC.position()==inC.size()){
                inC.close();
                outC.close();
                return new Date().getTime()-time;
            }
            if((inC.size()-inC.position())<20971520)
                length=(int)(inC.size()-inC.position());
            else
                length=20971520;
            inC.transferTo(inC.position(),length,outC);
            inC.position(inC.position()+length);
            i++;
        }
    }





    /**
     * 根据传入身份证号获取购票信息
     *
     * @param sfzhList 身份证号List
     * @return 购票信息List
     */
    private List<PCGTicket> queryTicketList(List<String> sfzhList) {
        Timestamp startTime = new Timestamp(new Date().getTime() - 1000 * 60 * 60 * 2); //获取最近两小时的购票信息
        List<PCGTicket> pcgTickets = policeInterfaceService.getPCGTicketList(sfzhList, startTime, null);
        return pcgTickets;
    }


    /**
     * 处理查询购票结果
     *
     * @param ticket   购票信息
     * @param infoList 布控信息List
     */
    private void handleTicket(PCGTicket ticket, List<DcInfo> infoList) {

        boolean dcFlag = false;
        for (DcInfo info: infoList
             ) {
            if (info.getCardNo().equals(ticket.getSfzh()))
            {
                dcFlag = true;
                break;
            }
        }

        if (!dcFlag)
        {
            return;
        }


        String key = ticket.getId();
        DcData dcData = iDcDataService.findByKey(key);
        if (dcData == null) //如果未记录在案
        {
            dcData = new DcData();
        }
        dcData.setNumber(ticket.getBc());
        dcData.setRealName(ticket.getXm());
        dcData.setCardType("身份证");
        dcData.setCardNo(ticket.getSfzh());
        dcData.setLeaveTime(ticket.getKcsj());
        dcData.setSpace(ticket.getCw());
        dcData.setStartAndEnd(ticket.getQzd());
        dcData.setBuyTime(ticket.getSpsj());
        dcData.setHaveTime(ticket.getJpsj());
        dcData.setKey(ticket.getId());
        dcData.setIsDelete(false);


        if (dcData.getId() != null) {
            iDcDataService.update(dcData); //更新售票信息
        } else {
            iDcDataService.save(dcData); //保存售票信息
            dcData = iDcDataService.findByKey(key);

            //筛选需要报警的布控信息
            List<DcInfo> alarmInfoList = new ArrayList<DcInfo>();
            for (DcInfo info : infoList) {
                if (info.getCardNo().equals(dcData.getCardNo()))
                {
                    alarmInfoList.add(info);
                }
            }

            //遍历需要报警的布控信息
            for (DcInfo info:alarmInfoList)
            {
                DcAlarm alarm = new DcAlarm();
                alarm.setAlarmDate(new Date());
                alarm.setInfoId(info.getId());
                alarm.setDcDataId(dcData.getId());
                iDcAlarmService.save(alarm); //保存报警信息

                //筛选报警信息需要通知的用户
                String alarmUserIds[] = info.getAlarmIds().split(",");
                //遍历报警信息需要通知的用户
                for (String userId:alarmUserIds) {
                    if (userId!=null&&!"".equals(userId))
                    {
                        //app报警信息
                        String alarmContent = "您有一条关于"+ticket.getXm()+"（"+ticket.getSfzh()+"）的新的报警信息。";
                        System.out.println(alarmContent);
                        JSONObject pushInfo = new JSONObject();
                        pushInfo.put("audit_type","alarm");
                        pushInfo.put("dataId",dcData.getId());

                        iddPushService.push(userId,"报警",alarmContent,pushInfo);

                        //获取需要通知的用户详细信息
                        CommonAdminuser user = iCommonAdminuserService.find(Long.parseLong(userId));

                        iDcSmsService.sendMessage(user.getPhone(),ticket.getInfoWithMask());
                    }
                }


            }
        }
    }


    /**
     * 同步购票人讯息
     * @param sfzh 身份证号
     */
    private void syncPeopleInfo(String sfzh)
    {
        DcPeople dcPeople = iDcPeopleService.findByCardNo(sfzh);
        if (dcPeople==null)
        {
            People people = policeInterfaceService.getPeopleBySfzh(sfzh);
            dcPeople = new DcPeople();
            dcPeople.setRealName(people.getXm());
            dcPeople.setOldRealName(people.getCym());
            dcPeople.setSex(people.getXb());
            dcPeople.setNationality(people.getMz());
            dcPeople.setBirthday(people.getCsrq());
            dcPeople.setAddressAreaCode(people.getZzssxq());
            dcPeople.setAddress(people.getZzxz());
            dcPeople.setCardNo(sfzh);
            dcPeople.setPhoto(people.getXp());
            iDcPeopleService.save(dcPeople);
        }
    }

    List<PCGTicket> getTicketListByFile(File xmlFile)
    {
        List<PCGTicket> resultList = new ArrayList<>();
        SAXReader reader = new SAXReader();
        try {
            Document document =reader.read(xmlFile);
            Iterator<Element> it = document.getRootElement().elementIterator("R1");
            while (it.hasNext())
            {
                Element element = it.next();
                String start = element.elementText("始发港");
                String end = element.elementText("到达港");
                String keyPrefix = "";
                if ("蓬莱".equals(start))
                {
                    keyPrefix = "PLG";
                }
                else {
                    keyPrefix = "CDG";
                }
                String key = keyPrefix + element.elementText("系统主键");
                String realName = element.elementText("旅客姓名");
                String cardType = element.elementText("证件类型");
                String cardNo = element.elementText("证件号码");
                String leaveTime = element.elementText("离港时间");
                String shipNumber = element.elementText("班次");
                String shipSpace = element.elementText("舱位");
                String buyTime = element.elementText("购票时间");
                String insertTime = element.elementText("入库时间");
                String updateTime = element.elementText("更新时间");
                String startAndEnd = start+"-"+end;
                PCGTicket ticket = new PCGTicket();
                ticket.setXm(realName);
                ticket.setSpsj(parseDate(buyTime));
                ticket.setSfzh(cardNo);
                ticket.setRksj(parseDate(insertTime));
                ticket.setQzd(startAndEnd);
                ticket.setKcsj(parseDate(leaveTime));
                ticket.setId(key);
                ticket.setBc(shipNumber);
                ticket.setCw(shipSpace);
                ticket.setGxsj(parseDate(updateTime));
                resultList.add(ticket);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultList;
    }

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    private Timestamp parseDate(String input)
    {
        try {
            return new Timestamp(sdf.parse(input).getTime());
        }catch (Exception e)
        {
            return null;
        }
    }


}

